package com.xu.t1.common;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * 通用redis分布式锁
 *
 * @author xu
 *
 */

@Component
public class RedisLockUtil {

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    // 无返回值的加锁
    public void runWithLock(String lockKey, Runnable task) {
        runWithLock(lockKey, 3, 30, TimeUnit.SECONDS, task);
    }

    public void runWithLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit, Runnable task) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.tryLock(waitTime, leaseTime, unit)) {
                try {
                    task.run();
                } finally {
                    lock.unlock();
                }
            }
        } catch (Exception e) {
            System.err.println("分布式锁异常（无返回值）：" + e.getMessage());
        }
    }

    // 有返回值的加锁
    public <T> T runWithLock(String lockKey, Supplier<T> task, T defaultValue) {
        return runWithLock(lockKey, 3, 30, TimeUnit.SECONDS, task, defaultValue);
    }

    public <T> T runWithLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit, Supplier<T> task, T defaultValue) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.tryLock(waitTime, leaseTime, unit)) {
                try {
                    //Thread.sleep(30000);  //redis分布式锁测试
                    return task.get();
                } finally {
                    lock.unlock();
                }
            } else {
                System.out.println("未获得锁，返回默认值: " + lockKey);
                return defaultValue;
            }
        } catch (Exception e) {
            System.err.println("分布式锁异常（有返回值）：" + e.getMessage());
            return defaultValue;
        }
    }
}